package dmas.lab.tasks;

import java.math.BigInteger;
import java.util.List;
import java.util.Random;

import dmas.lab.helpers.Helpers;
import dmas.lab.models.Contact;
import dmas.lab.models.Friend;
import dmas.lab.models.Group;
import dmas.lab.schedulers.Event;
import dmas.lab.schedulers.Scheduler;
import dmas.lab.schedulers.TaskCaller;

public class SendSpamEvent extends Event {

	private final BigInteger eventID;
	private double repostProbability;
	private final int authorID;
	private final int fromID;
	private Group group = Group.getGroup();

	public SendSpamEvent(BigInteger eventID, TaskCaller taskCaller, int toID, int fromID) {
		super(taskCaller);
		this.eventID = eventID;
		this.authorID = toID;
		this.fromID = fromID;

	}

	@Override
	public Object runTask() throws Exception {
		
		Contact authorContact = group.getContact(authorID);

		if (isReposting(authorContact)) {
			int numberOfFriends = authorContact.getFriends().size();
			int sendToCount = (int) (numberOfFriends * repostProbability);

			List<Friend> friends = authorContact.getFriends();
			for (Friend friend : friends) {
					if (sendToCount > 0 && friend.getState().equals("hated") || friend.getState().equals("neutral")) {
						Contact currentFriend = group.getContact(friend.getID());
						sendMessageToFriend(authorContact, currentFriend);
						
						sendToCount--;
					}
				}
		}
		return String.format("Event id: %s, Sender ID: %s, IGNORED", this.eventID, authorContact.getID());
	}

	private boolean isReposting(Contact authorContact) {
		return isProbable(authorContact) && (authorID != fromID);
	}

	private void sendMessageToFriend(Contact authorContact, Contact friend) {
		int indexOfChanged = friend.getFriends().indexOf(authorContact);
		Friend sendToFriend = authorContact;
		sendToFriend.setState("hated");
		friend.getFriends().set(indexOfChanged, sendToFriend);
		
		System.out.println(String.format("Event id: %s, Sender ID: %s, Receiver ID: %s", eventID, authorContact.getID(), friend.getID()));
		launchNewEvent(authorContact.getID(), friend.getID());
	}

	private void launchNewEvent(int fromID, int toID) {
		Scheduler scheduler = (Scheduler) getCallback();
		scheduler.addEvent(new SendSpamEvent(BigInteger.probablePrime(16, new Random()), scheduler, toID, fromID));
	}

	private boolean isProbable(Contact contact) {
		repostProbability = Helpers.getProbability(contact.getFriends().size(), group.getSize());
		double dd = Helpers.getRandomDouble();
		return (repostProbability >= dd);
	}

}